package com.cy.jdk8.stream.demo1;

import com.alibaba.fastjson.JSON;
import com.cy.User;
import com.cy.util.U;
import org.testng.annotations.Test;
import org.testng.collections.Lists;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author : yue.cao
 * @since : 2021-04-15
 */
public class StreamDemo1 {

	List<User> userList = Lists.newArrayList(
			new User(1, "1a"),
			new User(2, "2a"),
			new User(3, "3a"),
			new User(4, "4a"),
			new User(4, "4b")
	);

	@Test(description = "集合提取元素转集合")
	public void t1() {
		List<Integer> userIds = new ArrayList<>();
		for (User user : userList) {
			userIds.add(user.getUserId());
		}
		System.out.println(userIds);

		userIds = userList.stream().map(User::getUserId).collect(Collectors.toList());
		System.out.println(userIds);
	}

	@Test(description = "过滤")
	public void t2() {
		List<Integer> userIds = userList.stream().filter(item -> item.getUserId() % 2 == 0).map(User::getUserId).collect(Collectors.toList());
		System.out.println(userIds);
	}

	@Test(description = "过滤 && 去重")
	public void t3() {
		Set<Integer> userIds = userList.stream().filter(item -> item.getUserId() % 2 == 0).map(User::getUserId).collect(Collectors.toSet());
		System.out.println(userIds);
	}

	@Test(description = "类型转换")
	public void t4() {
		List<String> collect = userList.stream().map(x -> x.getUserId().toString()).collect(Collectors.toList());
		System.out.println(collect);
	}

	@Test(description = "数组 -> 集合")
	public void t5() {
		//创建一个字符串数组
		String[] strArray = new String[]{"a", "b", "c"};
		//转换后的List 属于 java.util.ArrayList 能进行正常的增删查操作
		List<String> strList = Stream.of(strArray).collect(Collectors.toList());
	}

	@Test(description = "集合 -> Map")
	public void t6() {
		Map<Integer, User> userMap = new HashMap<>();
		for (User user : userList) {
			userMap.put(user.getUserId(), user);
		}
		System.out.println(userMap);

		userMap = userList.stream().collect(Collectors.toMap(User::getUserId, v -> v, (k1, k2) -> k1));
		System.out.println(userMap);

		// 上文中的Collectors.toMap(User::getUserId, v -> v, (k1,k2) -> k1)，表达的意思就是
		// 将userId的内容作为key，
		// v -> v是表示将元素user作为value，
		// 其中(k1,k2) -> k1表示如果存在相同的key, k1 先来 k2 后来 则保留 k1对应的value 如果换成 k2 就和上面保持一致
	}

	@Test(description = "将集合转换成Map，将相同的key，加入到一个集合中，实现分组")
	public void t7() {
		Map<Integer, List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getUserId));
		System.out.println(JSON.toJSONString(userMap, true));
	}

	@Test(description = "分页操作")
	public void t8() {
		List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5, 10, 6, 20, 30, 40, 50, 60, 100);
		// skip参数表示第几行，limit表示查询的数量，类似页容量
		List<Integer> dataList = numbers.stream()
				.sorted((x, y) -> x.compareTo(y))
				.skip(0).limit(3).collect(Collectors.toList());
		System.out.println(dataList.toString());
	}

	@Test(description = "查找和匹配")
	public void t10() {
		List<Integer> list = Arrays.asList(10, 5, 7, 3);
		boolean allMatch = list.stream()
				.allMatch(x -> x > 2);//是否全部元素都大于2
		System.out.println(allMatch);

		// 返回第一个元素
		Optional<Integer> first = list.stream()
				.findFirst();
		Integer val = first.get();
		System.out.println(val);

		// 求和
		Integer result = list.stream()//
				.reduce(2, Integer::sum);
		System.out.println(result);
	}

	@Test(description = "并行操作")
	public void t11(){
		// 并行，指的是多个任务在同一时间点发生，并由不同的cpu进行处理，不互相抢占资源
		// 并发，指的是多个任务在同一时间点内同时发生了，但由同一个cpu进行处理，互相抢占资源
		// 这点上大家一定要区分清楚，别弄混了!
		// stream api 的并行操作和串行操作，只有一个方法区别，其他都一样，例如下面我们使用parallelStream来输出空字符串的数量

		List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
		// 采用并行计算方法，获取空字符串的数量
		long count = strings.parallelStream().filter(String::isEmpty).count();
		System.out.println(count);
	}
}
